import { jsx, jsxs } from '@knno/jsx/jsx-runtime';
import SVGH5 from '@mdi/svg/svg/language-html5.svg';
import * as esbuild from 'esbuild-wasm';
import { Action } from '../../components/action/action';
import {
	Button,
	ButtonDanger,
	ButtonPrimary,
	ButtonSuccess,
	ButtonWarning,
} from '../../components//button/button';
import { Calendar } from '../../components/calendar/calendar';
import { ColorPicker } from '../../components/colorPicker/colorPicker';
import { Datebox } from '../../components/datebox/datebox';
import { DatePicker } from '../../components/datePicker/datePicker';
import { Dialog } from '../../components/dialog/dialog';
import { Empty } from '../../components/empty/empty';
import { Files } from '../../components/files/files';
import { Foldable } from '../../components/foldable/foldable';
import { FoldableMenu } from '../../components/foldableMenu/foldableMenu';
import {
	Capability,
	FormControl,
	type FormControlDefinition,
	type MenuItem,
	type Problem,
	type RenderState,
} from '../../components/form/formControl';
import { Grid } from '../../components/grid/grid';
import { Icon } from '../../components/icon/icon';
import { Input } from '../../components/input/input';
import { InputGrid } from '../../components/inputGrid/inputGrid';
import { List } from '../../components/list/list';
import { ListInput } from '../../components/listInput/listInput';
import { Loading } from '../../components/loading/loading';
import { Mask } from '../../components/mask/mask';
import { Pager } from '../../components/pager/pager';
import { Picker } from '../../components/picker/picker';
import { PopList } from '../../components/popList/popList';
import { PopMenu } from '../../components/popMenu/popMenu';
import { Popup } from '../../components/popup/popup';
import { Progress } from '../../components/progress/progress';
import { Pulldown } from '../../components/pulldown/pulldown';
import { InlineEditor, RichEditor } from '../../components/richEditor/richEditor';
import { Roller } from '../../components/roller/roller';
import { Select } from '../../components/select/select';
import { Selector } from '../../components/selector/selector';
import { Splitter } from '../../components/splitter/splitter';
import { Tab } from '../../components/tab/tab';
import { Table } from '../../components/table/table';
import { TableList } from '../../components/tableList/tableList';
import { Tag } from '../../components/tag/tag';
import { Textarea } from '../../components/textarea/textarea';
import { Toast } from '../../components/toast/toast';
import { Waiting } from '../../components/waiting/waiting';
import { DICT } from '../../dict/dict';

const Library = {
	Button,
	ButtonPrimary,
	ButtonDanger,
	ButtonSuccess,
	ButtonWarning,
	Action,
	Calendar,
	ColorPicker,
	Datebox,
	DatePicker,
	Dialog,
	Empty,
	Files,
	Foldable,
	FoldableMenu,
	Grid,
	Icon,
	Input,
	InputGrid,
	List,
	ListInput,
	Loading,
	Mask,
	Pager,
	Picker,
	PopList,
	PopMenu,
	Popup,
	Progress,
	Pulldown,
	RichEditor,
	InlineEditor,
	Roller,
	Select,
	Selector,
	Splitter,
	Tab,
	Table,
	TableList,
	Tag,
	Textarea,
	Toast,
	Waiting,
};

const ready = esbuild.initialize({
	wasmURL: './esbuild.wasm',
	worker: true,
});

export type DynamicControlDef = FormControlDefinition & {
	js?: string;
	jsx?: string;
};

export class FormDynamicControl extends FormControl<DynamicControlDef> {
	static get name() {
		return DICT.dynamicControl;
	}
	static get icon() {
		return SVGH5;
	}
	static get type(): string {
		return 'dynamic';
	}
	override get capability(): Capability {
		return Capability.None;
	}
	get menu(): MenuItem[] {
		return [];
	}
	renderProps(): Node | void {}
	render(_: RenderState): Node {
		const source = this.definition.js;
		let node: Node | string;
		if (source) {
			const fn = new Function('jsx', 'jsxs', 'Lib', source);
			const valueHandler = ((control: this) => {
				return {
					set value(v: unknown) {
						control.setValue(v);
					},
					get value() {
						return control.value;
					},
				};
			})(this);
			try {
				node = fn.call(valueHandler, jsx, jsxs, Library);
			} catch (e) {
				node = (
					<code style={{ color: 'red', padding: '1em', wordBreak: 'break-word' }}>{e + ''}</code>
				);
			}
		} else {
			node = '';
		}
		return <div style={{ overflow: 'auto' }}>{node}</div>;

		// let div: HTMLDivElement;
		// // return unsafe(this.definition.value as string);
		// const jsxStr = `
		// return (<div style={{}}><a>hello</a><Knno.Button onClick={() =>{ Knno.Dialog.alert('ok') }}>card</Knno.Button><Knno.Calendar /></div>);
		// `;

		// ready
		// 	.then((result) => {
		// 		console.log('esbuild ready!');
		// 		return esbuild.transform(jsxStr, {
		// 			loader: 'jsx',
		// 			// jsx: 'transform',
		// 			// jsxImportSource: 'preact',
		// 			jsx: 'automatic',
		// 			jsxFactory: 'jx',
		// 		});
		// 	})
		// 	.then((result) => {
		// 		console.log(result.code);
		// 		const fn = new Function('jsx', 'jsxs', 'Knno', result.code.replace(/^import ([^;]+);/g, ''));
		// 		const node = fn(jsx, jsxs, Library);
		// 		// console.log(node);
		// 		div.replaceChildren(node);
		// 	})
		// 	.catch((reason) => console.log('transform failed:', reason));

		// return <div ref={(d) => (div = d)}></div>;
	}
	verify(): Problem[] {
		return [];
	}
	panels(): { name: string; panel: Node }[] {
		throw new Error('Method not implemented.');
	}
}
